/**
 * @description 通用于form 表单验证以及 其他校验验证
 * @Copyright (c) 2020 medo
 * @author medo_chen
 */
import validateTip from './validateTip'
/**
 * @description 判读是否为外链
 * @param path
 * @returns {boolean}
 */
export function isExternal(path) {
  return /^(https?:|mailto:|tel:)/.test(path)
}

/**
 * @description 校验密码是否小于6位
 * @param str
 * @returns {boolean}
 */
export function isPassword(str) {
  return str.length >= 6
}

/**
 * @description 密码以字母开头，长度在6~18之间，只能包含字母、数字和下划线
 * @returns {boolean}
 */
export function isPassword_limit(value) {
  // const reg = /^[a-z0-9_-]{8,16}$/
  const reg = /^[a-zA-Z]\w{7,15}$/
  return reg.test(value)
}

/**
 * @description 判断是否为数字
 * @param value
 * @returns {boolean}
 */
export function isNumber(value) {
  const reg = /^[0-9]*$/
  return reg.test(value)
}

/**
 * @description 判断是否为IP
 * @param ip
 * @returns {boolean}
 */
export function isIP(ip) {
  const reg =
    /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/
  return reg.test(ip)
}

/**
 * @description 判断是否是传统网站
 * @param url
 * @returns {boolean}
 */
export function isUrl(url) {
  const reg =
    /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&&%$#=~_-]+))*$/
  return reg.test(url)
}

/**
 * @description 判断是否是小写字母
 * @param str
 * @returns {boolean}
 */
export function isLowerCase(str) {
  const reg = /^[a-z]+$/
  return reg.test(str)
}

/**
 * @description 判断是否是大写字母
 * @param str
 * @returns {boolean}
 */
export function isUpperCase(str) {
  const reg = /^[A-Z]+$/
  return reg.test(str)
}

/**
 * @description 判断是否是大写字母开头
 * @param str
 * @returns {boolean}
 */
export function isAlphabets(str) {
  const reg = /^[A-Za-z]+$/
  return reg.test(str)
}

/**
 * @description 判断是否是字符串
 * @param str
 * @returns {boolean}
 */
export function isString(str) {
  return typeof str === 'string' || str instanceof String
}

/**
 * @description 判断是否是数组
 * @param arg
 * @returns {arg is any[]|boolean}
 */
export function isArray(arg) {
  if (typeof Array.isArray === 'undefined') {
    return Object.prototype.toString.call(arg) === '[object Array]'
  }
  return Array.isArray(arg)
}

/**
 * @description 判断是否是端口号
 * @param str
 * @returns {boolean}
 */
export function isPort(str) {
  const reg =
    /^([0-9]|[1-9]\d|[1-9]\d{2}|[1-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$/
  return reg.test(str)
}

/**
 * @description 判断是否是端口号
 * @param str
 * @returns {boolean}
 */
export function isPortLimits(str, min = 10000, max = 65535) {
  return str >= min && str <= max
}

/**
 * @description 判断是否是手机号
 * @param str
 * @returns {boolean}
 */
export function isPhone(str) {
  const reg = /^1\d{10}$/
  return reg.test(str)
}

/**
 * @description 判断是否是身份证号(第二代)
 * @param str
 * @returns {boolean}
 */
export function isIdCard(str) {
  const reg =
    /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/
  return reg.test(str)
}

/**
 * @description 判断是否是邮箱
 * @param str
 * @returns {boolean}
 */
export function isEmail(str) {
  const reg = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/
  return reg.test(str)
}

/**
 * @description 判断是否中文
 * @param str
 * @returns {boolean}
 */
export function isChina(str) {
  const reg = /^[\u4E00-\u9FA5]{2,4}$/
  return reg.test(str)
}

/**
 * @description 判断是否为空
 * @param str
 * @returns {boolean}
 */
export function isBlank(str) {
  return (
    str == null ||
    false ||
    str === '' ||
    str.trim() === '' ||
    str.toLocaleLowerCase().trim() === 'null'
  )
}

/**
 * @description 判断是否为固话
 * @param str
 * @returns {boolean}
 */
export function isTel(str) {
  const reg =
    /^(400|800)([0-9\\-]{7,10})|(([0-9]{4}|[0-9]{3})(-| )?)?([0-9]{7,8})((-| |转)*([0-9]{1,4}))?$/
  return reg.test(str)
}

/**
 * @description 判断是否为数字且最多两位小数
 * @param str
 * @returns {boolean}
 */
export function numm(str) {
  const reg = /^\d+(\.\d{1,2})?$/
  return reg.test(str)
}

/**
 * @description 判断经度 -180.0～+180.0（整数部分为0～180，必须输入1到15位小数）
 * @param str
 * @returns {boolean}
 */
export function isLongitude(str) {
  const reg =
    /^[-|+]?(0?\d{1,2}\.\d{1,15}|1[0-7]?\d{1}\.\d{1,15}|180\.0{1,15})$/
  return reg.test(str)
}

/**
 * @description 判断纬度 -90.0～+90.0（整数部分为0～90，必须输入1到15位小数）
 * @param str
 * @returns {boolean}
 */
export function isLatitude(str) {
  const reg = /^[-|+]?([0-8]?\d{1}\.\d{1,15}|90\.0{1,15})$/
  return reg.test(str)
}

/**
 * @description rtsp校验，只要有rtsp://
 * @param str
 * @returns {boolean}
 */
export function isRTSP(str) {
  const reg =
    /^rtsp:\/\/([a-z]{0,10}:.{0,10}@)?(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/
  const reg1 =
    /^rtsp:\/\/([a-z]{0,10}:.{0,10}@)?(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5]):[0-9]{1,5}/
  const reg2 =
    /^rtsp:\/\/([a-z]{0,10}:.{0,10}@)?(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\//
  return reg.test(str) || reg1.test(str) || reg2.test(str)
}

/**
 * @description 验证码长度
 * @param str
 * @returns {boolean}
 */
export function lengthLimit0_6(str) {
  return str.length >= 6
}
/**
 * @description 判断是否超过范围
 * @param str
 * @returns {boolean}
 */
export function lengthLimit0_10(str, min = 0, max = 10) {
  return str.length >= min && str.length <= max
}

/**
 * @description 判断是否超过范围
 * @param str
 * @returns {boolean}
 */
export function lengthLimit0_20(str, min = 0, max = 20) {
  return str.length >= min && str.length <= max
}

/**
 * @description 判断是否超过范围
 * @param str
 * @returns {boolean}
 */
export function lengthLimit0_30(str, min = 0, max = 30) {
  return str.length >= min && str.length <= max
}

/**
 * @description 判断是否超过范围
 * @param str
 * @returns {boolean}
 */
export function lengthLimit0_41(str, min = 0, max = 41) {
  return str.length >= min && str.length <= max
}

/**
 * @description 判断是否超过范围
 * @param str
 * @returns {boolean}
 */
export function lengthLimit0_50(str, min = 0, max = 50) {
  return str.length >= min && str.length <= max
}

/**
 * @description 判断是否超过范围
 * @param str
 * @returns {boolean}
 */
export function lengthLimit0_100(str, min = 0, max = 100) {
  return str.length >= min && str.length <= max
}

/**
 * @description 判断是否超过范围
 * @param str
 * @returns {boolean}
 */
export function lengthLimit0_500(str, min = 0, max = 500) {
  return str.length >= min && str.length <= max
}

/**
 * @description 判断是否超过范围
 * @param str
 * @returns {boolean}
 */
export function lengthLimit0_10000(str, min = 0, max = 10000) {
  return str >= min && str <= max
}

/**
 * @description 判断是否超过范围
 * @param str
 * @returns {boolean}
 */
export function lengthLimit0_100000(str, min = 0, max = 100000) {
  return str >= min && str <= max
}

/**
 * @description 端口范围限制
 * @param str
 * @returns {boolean}
 */
export function lengthLimit0_65535(str, min = 0, max = 65535) {
  return str >= min && str <= max
}

/**
 * @description 判断是否是正确的版本
 * @param str
 * @returns {boolean}
 */
export function isVersion(str) {
  // const reg = /^(\d{1,3}\.){2,3}\d$/
  const reg = /^([1-9]\d|[1-9])(\.([1-9]\d|\d)){2}$/
  return reg.test(str)
}

/**
 * @description 判断ENU字段,保留6位小数，限制12字符
 * @param str
 * @returns {boolean}
 */
export function isENU(str, min = 0, max = 12) {
  const reg = /^\d{1,12}(\.?\d{0,6})$/g
  return reg.test(str) && str.length >= min && str.length <= max
}

function valid(val, isPass) {
  return { result: isPass, errMsg: validateTip[val] || validateTip['default'] }
}

// required:Boolean 是否必填项，选填，默认"true"
// type:String/Function 校验类型，选填，
//     String时必须是上面存在的函数名，若存在多个校验规则可通过'|'分开，如：'isNumber|isTel'
//     Function时只接收一个参数(输入值)，返回格式： {result:Boolean, errMsg:String}
// trigger:String 触发动作，选填，默认"blur"
// nullMsg:String 未输入的提示语，选填，required=true时有效
export function validateRule(
  required = true,
  type,
  trigger = 'blur',
  nullMsg = '该字段为必填项'
) {
  const rule = { required: !!required, trigger }

  let check = null
  if (typeof type === 'function') {
    check = type
  } else {
    check = type ? type + '' : null
  }

  if (check) {
    // 存在规则时添加规则
    rule.validator = (r, v, c) => {
      let data = null
      if (typeof type === 'string') {
        const array = type.split('|')
        array.every((item) => {
          // eslint-disable-next-line no-eval
          console.log('item----------', item)
          data = valid(item, eval(item + "('" + v + "')"))
          console.log('data----------', data)
        })
      } else {
        data = check(v)
      }
      const { result, errMsg } = data
      if (required) {
        // 必填项: null,undefined,"","  " 都算无输入内容
        return v == null || (v + '').trim() === ''
          ? c(new Error(nullMsg))
          : result
          ? c()
          : c(new Error(errMsg))
      }
      // 选填项: null,undefined,"" 都算无输入内容，"  "会被校验
      return v == null || v + '' === '' || result ? c() : c(new Error(errMsg))
    }
  } else {
    rule.message = nullMsg
  }
  return [rule]
}
